#include "fadeeffect.h"
//#include "vectorproperties.h"
#include "datatypedefine.h"
#include "transformableactor.h"
#include <osg\StateSet>
#include <osg\Node>
#include <osg\BlendFunc>
#include <osg\BlendColor>
#include <osg\Material>
#include <osg\Depth>

namespace VrDataCore
{
	FadeEffect::FadeEffect():_fadeIn(true),_fadeCallback(NULL),_updateA(false)
	{
		_motion = new osgAnimation::InOutCubicMotion;
	}

	FadeEffect::~FadeEffect()
	{}

	void FadeEffect::buildPropertyMap()
	{
		EffectBase::buildPropertyMap();
	}

	void FadeEffect::apply( CoreBase::ActorBase* actor)
	{
		if(_fadeIn)
			_materialEffect = osg::Vec4(1.0f,1.0f,1.0f,0.0f);
		else
			_materialEffect = osg::Vec4(1.0f,1.0f,1.0f,0.999f);
		dynamic_cast<TransformableActor*>(actor)->setUseDefaultStateSet(false);
		dynamic_cast<TransformableActor*>(actor)->useStateSet();
		osg::Node* node = actor->getDrawable()->getOSGNode();
		osg::StateSet* usestateset = node->getStateSet();
		osg::ref_ptr<osg::Material> mat = new osg::Material;
		mat->setColorMode(osg::Material::ColorMode::EMISSION);
		mat->setEmission( osg::Material::FRONT,_materialEffect);
		mat->setAlpha(osg::Material::Face::FRONT_AND_BACK,_materialEffect.a());
		usestateset->setAttributeAndModes(mat,osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
		if(!_fadeCallback.valid())
		{
			_fadeCallback = new FadeCallback(this);
			node->addUpdateCallback(_fadeCallback);
		}
		EffectBase::apply(actor);
		_updateA = true;
		_motion->reset();
	}

	void FadeEffect::unApply( CoreBase::ActorBase* actor)
	{
		if(isIdle())
			return;
		osg::Node* node = _bindingMeshDrawableActor->getDrawable()->getOSGNode();
		if(_fadeCallback.valid())
			node->removeUpdateCallback(_fadeCallback);
		EffectBase::unApply(actor);
		_motion->reset();
		_updateA = false;
	}

	bool FadeEffect::isUpdating()
	{
		return _updateA;
	}

	void FadeEffect::update()
	{
		if(_updateA)
		{
			osg::Node* node = _bindingMeshDrawableActor->getDrawable()->getOSGNode();
			osg::StateSet* usestateset = node->getStateSet();
			_motion->update(0.008);
			float alpha = _motion->getValue();
			if(_fadeIn)
			{
				_materialEffect.a() = alpha;
			}
			else
			{
				_materialEffect.a() = 1.0-alpha;
			}
			osg::Material* mat = (osg::Material*)usestateset->getAttribute(osg::StateAttribute::MATERIAL);
			mat->setAlpha(osg::Material::Face::FRONT_AND_BACK,_materialEffect.a());
			if(alpha>=1.0)
			{
				_updateA = false;
				if(_fadeIn)
				{
					osg::Material* mat = (osg::Material*)usestateset->getAttribute(osg::StateAttribute::MATERIAL);
					usestateset->setAttributeAndModes(mat,osg::StateAttribute::OFF);
					dynamic_cast<TransformableActor*>(_bindingMeshDrawableActor)->useStateSet(false);
				}
			}
		}
	}

	void FadeEffect::fadeIn(bool in)
	{
		_fadeIn = in;
	}
}